package assignment.ton.gui;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.regex.PatternSyntaxException;

import javax.swing.AbstractAction;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import assignment.ton.def.Action;
import assignment.ton.def.Class;
import assignment.ton.def.Parameter;
import assignment.ton.def.Util;
import assignment.ton.gui.interfaces.AddParameterInterface;
import assignment.ton.gui.listener.ClassFrameActionListener;
/**
 * Responsible for added and editing a class
 * @author Tim
 */
public class ClassFrame extends JFrame implements AddParameterInterface{
	private static final long serialVersionUID = -7999034950604362773L;
	private Class inputClass;
	private JLabel nameText,varsText; 
	private JTextField nameField;
	private ClassFrameActionListener classListener;
	private JComboBox constructorList;
	private JButton addConstructor, delConstructor, okButton, cancelButton, editExtra;
	private JPanel bottomPanel;
	private DrawPanel drawPanel;
	private MainFrame mainFrame;
	private Action initialAction;
	public ClassFrame(Class iC, DrawPanel dP, MainFrame mF){
		initialAction = mF.getPreviousAction();
		this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		final ClassFrame iAm = this;
		this.addWindowListener(new WindowAdapter(){ //now make it do something more interesting
			public void windowClosing(WindowEvent e){
					iAm.dispose();
					classListener.cancel();
					if(initialAction==Action.ADDCLASS2||initialAction==Action.ADDCLASS){
						mainFrame.setAction(Action.NONE);
					}else{
						mainFrame.setAction(Action.CLASSSELECTED);
					}
			}
		});
		AbstractAction submitAction = new AbstractAction("Submit"){
			private static final long serialVersionUID = 7257370255554900955L;
			public void actionPerformed(ActionEvent e){
				submit();
				drawPanel.repaint();
			}
		};
		this.setIconImage(new ImageIcon(getClass().getResource("ton_icon.gif")).getImage());
		inputClass = iC;
		drawPanel = dP;
		mainFrame = mF;
		classListener = new ClassFrameActionListener(this, inputClass, mainFrame);
		this.setTitle("Class Properties");
		this.setResizable(false);
		this.setLayout(new GridBagLayout());
		this.setLocationRelativeTo(mainFrame);
		GridBagConstraints c = new GridBagConstraints();
		c.insets = new Insets(2,2,2,2);
		//name text
		nameText = new JLabel("Name");
		c.fill = GridBagConstraints.HORIZONTAL;
		c.gridx = 0;
		c.gridy = 0;
		c.gridwidth = 1;
		this.add(nameText, c);
		//name entry field
		nameField = new JTextField(inputClass.getName(),20);
		c.fill = GridBagConstraints.HORIZONTAL;
		c.gridx = 1;
		c.gridy = 0;
		c.gridwidth = 3;
		this.add(nameField, c);
		nameField.setAction(submitAction);
		//jlabel constructor parameters
		varsText = new JLabel("Constructor Parameters");
		c.fill = GridBagConstraints.HORIZONTAL;
		c.gridx = 0;
		c.gridy = 1;
		c.gridwidth = 1;
		this.add(varsText,c);
		//dropbox
		String [] data = inputClass.getConstructorList();
		constructorList = new JComboBox(data);
		c.fill = GridBagConstraints.HORIZONTAL;
		c.gridx = 0;
		c.gridy = 2;
		c.gridwidth = 2;
		this.add(constructorList, c);
		//add
		addConstructor = new JButton("Add");
		c.fill = GridBagConstraints.HORIZONTAL;
		c.gridx = 2;
		c.gridy = 2;
		c.gridwidth = 1;
		this.add(addConstructor, c);
		addConstructor.addActionListener(classListener);
		//delete
		delConstructor = new JButton("Delete");
		c.fill = GridBagConstraints.HORIZONTAL;
		c.gridx = 3;
		c.gridy = 2;
		c.gridwidth = 1;
		this.add(delConstructor, c);
		delConstructor.addActionListener(classListener);
		//the bottom panel
		bottomPanel = new JPanel();
		okButton = new JButton("Submit");
		okButton.addActionListener(classListener);
		bottomPanel.add(okButton);
		cancelButton = new JButton("Cancel");
		cancelButton.addActionListener(classListener);
		bottomPanel.add(cancelButton);
		editExtra = new JButton("Edit Extra Code");
		editExtra.addActionListener(classListener);
		bottomPanel.add(editExtra);
		c.fill = GridBagConstraints.HORIZONTAL;
		c.gridx = 0;
		c.gridy = 3;
		c.gridwidth = 4;
		this.add(bottomPanel, c);
		pack();
	}
	public void cancel(){
		if(initialAction==Action.ADDCLASS){
			mainFrame.setAction(Action.NONE);
		}else{
			mainFrame.setAction(Action.CLASSSELECTED);
		}
		this.dispose();
		
	}
	public void submit(){
		String name = nameField.getText();
		if(name.equals("")==true){ Util.showError(this, "Name cannot be blank"); return; } 
		name = name.substring(0,1).toUpperCase()+name.substring(1);
		if(name.equals(nameField.getText())==false){
			Util.showError(this, "Must start with uppercase");
			return;
		}
		name = name.trim().replaceAll(" +", "");
		if(name.equals(nameField.getText())==false){
			Util.showError(this, "Must not contain white spaces");
			return;
		}
		name = name.replaceAll("[^A-Za-z]", "");
		if(name.equals(nameField.getText())==false){
			Util.showError(this, "Name must only be alphanumeric");
			return;
		}
		if(mainFrame.getAction()==Action.ADDCLASS||mainFrame.getAction()==Action.ADDCLASS2||mainFrame.getAction()==Action.ADDCONSTRUCTOR){
			if(drawPanel.findClass(name)!=null){
				Util.showError(this, "Name is taken!");
				return;
			}
		}
		inputClass.setName(nameField.getText());
		mainFrame.setAction(Action.CLASSSELECTED);
		drawPanel.addClassToList(inputClass);
		drawPanel.repaint();
		this.dispose();
	}
	/**
	 * Attempts to remove the selected constructor item
	 */
	public void deleteConstructorItem(){
		try{
			String theType = (String)constructorList.getSelectedItem();
			String[] typeArray = theType.split(":");
			theType = typeArray[0];
			inputClass.removeConstructorParameter(theType);
			rebuildList();
		}catch(PatternSyntaxException f){
			Util.showError(this, "Quit trying to delete nothing");
		}

	}
	/**
	 * This method removed all items from the list and rebuilds it
	 */
	public void rebuildList(){
		constructorList.removeAllItems();
		String[] data = inputClass.getConstructorList();
		for(int i=0; i<data.length; i++){
			constructorList.addItem(data[i]);
		}
		pack();
	}
	@Override
	public void addParameter(Parameter p) {
		inputClass.addConstructorParameter(p);
	}
}
